package com.yuneec.fly.fragments;

import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.yuneec.fly.GlobalParams;
import com.yuneec.fly.R;
import com.yuneec.fly.events.EventBusFactory;
import com.yuneec.fly.events.uiEvent.ChangeMapToolsVisibleEvent;
import com.yuneec.fly.events.uiEvent.CurrentWaypointEvent;
import com.yuneec.fly.events.uiEvent.HideInsertPointEvent;
import com.yuneec.fly.events.uiEvent.InsertOnePointEvent;
import com.yuneec.fly.events.uiEvent.LandFinishEvent;
import com.yuneec.fly.events.uiEvent.LoadPointsEvent;
import com.yuneec.fly.events.uiEvent.MissionStatusChangeEvent;
import com.yuneec.fly.events.uiEvent.PointCircleEvent;
import com.yuneec.fly.events.uiEvent.PointRotateAngleEvent;
import com.yuneec.fly.events.uiEvent.RemoveOneInterestPointEvent;
import com.yuneec.fly.events.uiEvent.RemoveOnePointEvent;
import com.yuneec.fly.events.uiEvent.RouteTypeChangedEvent;
import com.yuneec.fly.events.uiEvent.SetControllerLocationEvent;
import com.yuneec.fly.events.uiEvent.SetDroneLocationEvent;
import com.yuneec.fly.events.uiEvent.SetFenceMarkerDraggableEvent;
import com.yuneec.fly.events.uiEvent.SetPanAndTiltAngle;
import com.yuneec.fly.events.uiEvent.SwitchMapActionEvent;
import com.yuneec.fly.utils.SharePrefUtil;
import com.yuneec.fly.views.AbstractMapView;
import com.yuneec.fly.views.AmapView;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

/**
 * Created by jw.gu on 2016/6/12.
 */
public class MapFragment extends BaseFragment implements View.OnClickListener {
    public static final int SELECT_MAP_TYPE_AUTO = 0;
    public static final int SELECT_MAP_TYPE_GMAP = 1;
    public static final int SELECT_MAP_TYPE_AMAP = 2;
    private AbstractMapView mapView;
    public FrameLayout mapViewContainer;
    private LinearLayout mapTypeSelectLayout;
    private LinearLayout locationBtnsLayout;
    private RelativeLayout mapTypeNormalLayout;
    private RelativeLayout mapTypeSatelliteLayout;
    private RelativeLayout mapTypeNightLayout;
    private TextView mapTypeNormalTV;
    private TextView mapTypeSatelliteTV;
    private TextView mapTypeNightTV;
    private LinearLayout longClickMenuLayout;
    private int textBgColor;
    private double insertLatitude;
    private double insertLongitude;
    private Bundle savedInstanceState;
    private Button changeMapTypeBtn;
    private Button showLocationBtn;
    private boolean getLocation;
    private AbstractMapView.InitCompleteListener listener;
    private AmapView amapView;

    @Override
    protected int getContentViewResourceId() {
        return R.layout.map;
    }

    @Override
    public void init(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getLocation = false;
        this.savedInstanceState = savedInstanceState;

        textBgColor = getResources().getColor(R.color.selected_map_type_textview_bg);

        locationBtnsLayout = (LinearLayout) selfView.findViewById(R.id.locationBtnsLayout);
        mapTypeSelectLayout = (LinearLayout) selfView.findViewById(R.id.mapTypeSelectLayout);
        mapTypeNightLayout = (RelativeLayout) selfView.findViewById(R.id.mapTypeNightLayout);
        mapTypeSatelliteLayout = (RelativeLayout) selfView.findViewById(R.id.mapTypeSatelliteLayout);
        mapTypeNormalLayout = (RelativeLayout) selfView.findViewById(R.id.mapTypeNormalLayout);

        mapTypeNormalTV = (TextView) selfView.findViewById(R.id.mapTypeNormalTV);
        mapTypeSatelliteTV = (TextView) selfView.findViewById(R.id.mapTypeSatelliteTV);
        mapTypeNightTV = (TextView) selfView.findViewById(R.id.mapTypeNightTV);

        mapViewContainer = (FrameLayout) selfView.findViewById(R.id.mapViewContainer);
        longClickMenuLayout = (LinearLayout) selfView.findViewById(R.id.longClickMenuLayout);

        mapTypeNormalLayout.setOnClickListener(selectMapListener);
        mapTypeSatelliteLayout.setOnClickListener(selectMapListener);
        mapTypeNightLayout.setOnClickListener(selectMapListener);

        changeMapTypeBtn = (Button) selfView.findViewById(R.id.changeMapTypeBtn);
        showLocationBtn = (Button) selfView.findViewById(R.id.showLocationBtn);
        changeMapTypeBtn.setOnClickListener(this);
        showLocationBtn.setOnClickListener(this);
        selfView.findViewById(R.id.insertPointBtn).setOnClickListener(this);
        selfView.findViewById(R.id.moveToDroneBtn).setOnClickListener(this);
        selfView.findViewById(R.id.moveToControllerBtn).setOnClickListener(this);
        listener = new AbstractMapView.InitCompleteListener() {
            @Override
            public void onInitComplete() {
                if (!getLocation) {
                    float lat = SharePrefUtil.getFloat(getActivity(), SharePrefUtil.KEY.KEY_LAST_CONTROLLER_LATITUDE, 0);
                    float lon = SharePrefUtil.getFloat(getActivity(), SharePrefUtil.KEY.KEY_LAST_CONTROLLER_LONGITUDE, 0);
                    if (mapView != null && lat != 0 && lon != 0) {
                        mapView.drawControllerMarker(lat, lon);
                    }
                }
            }
        };
    }

    public void setMapView() {
        addMapView(AmapView.class);
    }

    @Override
    public void onClick(View v) {
        if (mapView != null) {
            try {
                switch (v.getId()) {
                    case R.id.insertPointBtn:
                        longClickMenuLayout.setVisibility(View.GONE);
                        mapView.removeLongClickMarker();
                        break;
                    case R.id.changeMapTypeBtn:
                        if (locationBtnsLayout.getVisibility() == View.VISIBLE) {
                            locationBtnsLayout.setVisibility(View.GONE);
                        } else {
                            if (mapTypeSelectLayout.getVisibility() == View.VISIBLE) {
                                mapTypeSelectLayout.setVisibility(View.GONE);
                            } else {
                                mapTypeSelectLayout.setVisibility(View.VISIBLE);
                            }
                        }
                        break;
                    case R.id.moveToDroneBtn:
                        if (mapView != null) {
                            mapView.moveCameraToDroneLocation();
                        }
                        locationBtnsLayout.setVisibility(View.GONE);
                        break;
                    case R.id.moveToControllerBtn:
                        if (mapView != null) {
                            mapView.moveCameraToControllerLocation();
                        }
                        locationBtnsLayout.setVisibility(View.GONE);
                        break;
                    case R.id.showLocationBtn:
                        if (mapTypeSelectLayout.getVisibility() == View.VISIBLE) {
                            mapTypeSelectLayout.setVisibility(View.GONE);
                        } else {
                            if (locationBtnsLayout.getVisibility() == View.VISIBLE) {
                                locationBtnsLayout.setVisibility(View.GONE);
                            } else {
                                locationBtnsLayout.setVisibility(View.VISIBLE);
                            }
                        }
                        break;
                    case R.id.mapViewContainer:

                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void addMapView(Class clz) {
        if (mapView != null && mapView.getClass() == clz) {
            return;
        }
        GlobalParams.resetGeofence();
//        mapViewContainer.removeAllViews();
        if (mapView != null) {
            mapView.onPause();
//            this.mapView.onDestroy();
            mapView.setVisibility(View.GONE);
        }
        if (amapView == null) {
            amapView = new AmapView(getActivity(), savedInstanceState, MapFragment.this, listener);
            mapViewContainer.addView(amapView);
        } else {
            amapView.setVisibility(View.VISIBLE);
        }
        mapView = amapView;
        if (mapView instanceof AmapView) {
            mapTypeNightLayout.setVisibility(View.VISIBLE);
        } else {
            mapTypeNightLayout.setVisibility(View.GONE);
        }
        changeMapSelectUI(mapView.getMapType());

        mapView.onResume();
    }

    private View.OnClickListener selectMapListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mapView == null) {
                return;
            }
            try {
                switch (v.getId()) {
                    case R.id.mapTypeNormalLayout:
                        mapView.setMapType(AbstractMapView.MapType.NORMAL);
                        mapTypeNormalTV.setBackgroundColor(textBgColor);
                        mapTypeSatelliteTV.setBackgroundColor(Color.TRANSPARENT);
                        mapTypeNightTV.setBackgroundColor(Color.TRANSPARENT);
                        break;
                    case R.id.mapTypeSatelliteLayout:
                        mapView.setMapType(AbstractMapView.MapType.SATELLITE);
                        mapTypeNormalTV.setBackgroundColor(Color.TRANSPARENT);
                        mapTypeSatelliteTV.setBackgroundColor(textBgColor);
                        mapTypeNightTV.setBackgroundColor(Color.TRANSPARENT);
                        break;
                    case R.id.mapTypeNightLayout:
                        mapView.setMapType(AbstractMapView.MapType.NIGHT);
                        mapTypeNormalTV.setBackgroundColor(Color.TRANSPARENT);
                        mapTypeSatelliteTV.setBackgroundColor(Color.TRANSPARENT);
                        mapTypeNightTV.setBackgroundColor(textBgColor);
                        break;
                }
                changeMapSelectUI(mapView.getMapType());
                mapTypeSelectLayout.setVisibility(View.GONE);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    private void changeMapSelectUI(AbstractMapView.MapType mapType) {
        switch (mapType) {
            case NORMAL:
                mapTypeNormalTV.setBackgroundColor(textBgColor);
                mapTypeSatelliteTV.setBackgroundColor(Color.TRANSPARENT);
                mapTypeNightTV.setBackgroundColor(Color.TRANSPARENT);
                break;
            case SATELLITE:
                mapTypeNormalTV.setBackgroundColor(Color.TRANSPARENT);
                mapTypeSatelliteTV.setBackgroundColor(textBgColor);
                mapTypeNightTV.setBackgroundColor(Color.TRANSPARENT);
                break;
            case NIGHT:
                mapTypeNormalTV.setBackgroundColor(Color.TRANSPARENT);
                mapTypeSatelliteTV.setBackgroundColor(Color.TRANSPARENT);
                mapTypeNightTV.setBackgroundColor(textBgColor);
                break;
        }
    }

    public void showLongClickMenu(float x, float y, double latitude, double longitude) {
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) longClickMenuLayout.getLayoutParams();
        layoutParams.leftMargin = (int) x + 20;
        layoutParams.topMargin = (int) y - 50;
        longClickMenuLayout.setLayoutParams(layoutParams);
        longClickMenuLayout.setVisibility(View.VISIBLE);
        this.insertLatitude = latitude;
        this.insertLongitude = longitude;
    }

    public void hideLongClickMenu() {
        longClickMenuLayout.setVisibility(View.GONE);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onChangeMapToolsVisible(ChangeMapToolsVisibleEvent event) {
        mapTypeSelectLayout.setVisibility(View.GONE);
        locationBtnsLayout.setVisibility(View.GONE);
        changeMapTypeBtn.setVisibility(event.visible ? View.VISIBLE : View.GONE);
        showLocationBtn.setVisibility(event.visible ? View.VISIBLE : View.GONE);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onRemoveOnePoint(RemoveOnePointEvent event) {
        if (mapView != null) {
            mapView.onPointDelete(event.pointIndex + 1);
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onRemoveOneInterestPoint(RemoveOneInterestPointEvent event) {
        if (mapView != null) {
            mapView.onInterestPointDelete(event.index);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onInsertOnePoint(InsertOnePointEvent event) {
        if (mapView != null) {
            mapView.insertOnePoint(event.index, event.latitude, event.longitude);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onHideInsertPoint(HideInsertPointEvent event) {
        longClickMenuLayout.setVisibility(View.GONE);
        if (mapView != null) {
            mapView.removeLongClickMarker();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onPointCircle(PointCircleEvent event) {
        if (mapView != null) {
            mapView.addPointCircle(event.index, event.radius);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onPointRotateAngle(PointRotateAngleEvent event) {
        if (mapView != null) {
            mapView.changeMarkerRotateAngle(event.index, event.targetAngle);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSetDroneLocation(SetDroneLocationEvent event) {
        if (mapView != null && event.latitude != 0 && event.longitude != 0) {
            mapView.drawDroneMarker(event.latitude, event.longitude, event.routeAngle);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSetPanAngle(SetPanAndTiltAngle event) {
        if (mapView != null) {
            mapView.setPanAngle(event.panAngle);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSetControllerLocation(SetControllerLocationEvent event) {
        if (!getLocation) {
            getLocation = true;
//            String timeZone = TimeZoneMapper.latLngToTimezoneString(event.latitude,event.longitude);
//            if (!timeZone.equals("unknown")) {
//                String mapType;
//                if ("Asia/Shanghai".equals(timeZone)
//                        ||"Asia/Chongqing".equals(timeZone)
//                        ||"Asia/Urumqi".equals(timeZone)
//                        ||"Asia/Beijing".equals(timeZone)) {
//                    addMapView(new AmapView(getActivity(),savedInstanceState,MapFragment.this,null));
//                    mapType="AmapView";
//                }else{
//                    addMapView(new GoogleMapView(getActivity(),savedInstanceState,MapFragment.this,null));
//                    mapType="GoogleMapView";
//                }
//                SharePrefUtil.saveString(getActivity(),SharePrefUtil.KEY.KEY_LAST_MAP_TYPE,mapType);
//            }
            if (mapView != null && event.latitude != 0 && event.longitude != 0) {
                mapView.drawControllerMarker(event.latitude, event.longitude);
            }
        } else if (mapView != null && event.latitude != 0 && event.longitude != 0) {
            mapView.drawControllerMarker(event.latitude, event.longitude);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onLoadPoints(LoadPointsEvent event) {
        if (mapView != null) {
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSwitchMapAction(SwitchMapActionEvent event) {
        if (mapView != null) {
            GlobalParams.landLatLng = null;
            if (event.actionType == SwitchMapActionEvent.ActionType.POINT) {
                mapView.setPointMarkerDraggable(true && GlobalParams.getMissionStaus() == GlobalParams.MissionStatus.NONE);
            } else if (event.actionType == SwitchMapActionEvent.ActionType.FENCE) {
                mapView.exitPointType();
                if (GlobalParams.addingFence) {
                    mapView.checkFenceMapZoom();
                }
            } else if (event.actionType == SwitchMapActionEvent.ActionType.NONE) {
//                mapView.clearMap();
//                mapView.setPointMarkerDraggable(false);
            } else if (event.actionType == SwitchMapActionEvent.ActionType.HIDE) {
                mapView.clearMap();
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onLandPrepareFinish(LandFinishEvent event) {
        if (mapView != null) {
            mapView.removeLandPointMarker();
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onCurrentWaypoint(CurrentWaypointEvent event) {
        if (mapView != null &&
                (GlobalParams.getMissionStaus() == GlobalParams.MissionStatus.WAYPOINT_RUNNING || GlobalParams.getMissionStaus() == GlobalParams.MissionStatus.WAYPOINT_PAUSE)) {
            mapView.setCurrentWaypointIndex(event.index);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onRouteTypeChanged(RouteTypeChangedEvent event) {
        if (mapView != null) {
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMissionStatusChange(MissionStatusChangeEvent event) {
        if (mapView != null) {
            mapView.setLandPointMarkerDraggable(GlobalParams.getMissionStaus() != GlobalParams.MissionStatus.LAND_RUNNING);
            if (GlobalParams.getMissionStaus() == GlobalParams.MissionStatus.NONE) {
                mapView.removeLandPointMarker();
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSetFenceMarkerDraggable(SetFenceMarkerDraggableEvent event) {
        if (mapView != null) {
            mapView.setFenceMarkerDraggable(event.draggable);
        }
    }

    @Override
    public void onStart() {
        EventBusFactory.getUiBus().register(this);
        EventBusFactory.getFeedBackBus().register(this);
        super.onStart();
    }

    @Override
    public void onStop() {
        EventBusFactory.getUiBus().unregister(this);
        EventBusFactory.getFeedBackBus().unregister(this);
        super.onStop();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mapView != null) {
            mapView.onPause();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mapView != null) {
            mapView.onResume();
        }
        setMapView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (amapView != null) {
            amapView.onDestroy();
        }
    }
}
